import { ControlNode } from "./ControlNode";
import { NodeStatus } from "../NodeStatus";


/**
 * 如果某个子节点返回RUNNING，返回RUNNING，且下次tick()时之前的子节点会再次执行，reactive所在。
 * 如果某个子节点返回SUCCESS，不再执行，且返回SUCCESS。
 * 如果某个子节点返回FAILURE，立即执行下一个子节点（不会等下一次tick()）。如果所有子节点返回FAILURE，返回FAILURE。
 */
export class ReactiveFallback<T> extends ControlNode<T> {

    constructor(name: string,blackboard: T) {
        super(name,blackboard);
    }

    Tick(): NodeStatus {
        let failure_count: number = 0;
        for (let index = 0; index < this.numChildren; index++) {
            const child = this.$children[index];
            const child_status = child.Evaluate();
            switch (child_status) {
                case NodeStatus.RUNNING:
                    this.HaltChildren(index + 1);
                    return NodeStatus.RUNNING;
                case NodeStatus.FAILURE:
                    failure_count++;
                    break;
                case NodeStatus.SUCCESS:
                    this.HaltChildren();
                    return NodeStatus.SUCCESS;
                case NodeStatus.IDLE:
                    throw new Error("ReactiveFallback: child node is idle");
                default:
                    throw new Error("ReactiveFallback: unknown child node status");
            }
        }
        if (failure_count == this.numChildren) {
            this.HaltChildren();
            return NodeStatus.FAILURE;
        }
        return NodeStatus.RUNNING;
    }
}